package com.justcan.demo.cartoon.utils.anim;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.HandlerThread;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;


public class AnimSurfaceView extends SurfaceView implements AnimFrameController.IAnimFrameListener, IAnimView {

	/**
	 * 是否已经测量完成
	 */
	protected boolean mHadSize = false;
	/**
	 * 是否创建了Surface
	 */
	protected volatile boolean mHasSurfaceCreated = false;
	/**
	 * 绘制Rect
	 */
	protected Rect mDrawRect = null;
	/**
	 * 一组AnimObjectGroup
	 */
	protected List<AnimObjectGroup> mAnimObjectGroups = new ArrayList<AnimObjectGroup>();
	/**
	 * 动画帧控制器
	 */
	protected AnimFrameController mAnimFrameController = null;
	/**
	 * 动画时钟
	 */
	protected AnimClock mAnimClock = null;
	/**
	 * 绘制子线程
	 */
	protected HandlerThread mDrawThread = null;
	/**
	 * SurfaceView必备Callback
	 */
	protected Callback mSurfaceCallback = new Callback() {

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			mHasSurfaceCreated = false;
			mAnimFrameController.stop();
		}

		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			mHasSurfaceCreated = true;
		}

		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
								   int height) {
			mHadSize = true;
			if (mDrawRect == null) {
				mDrawRect = new Rect();
			}
			mDrawRect.set(0, 0, width, height);
			for (int i = 0; i < mAnimObjectGroups.size(); i++) {
				mAnimObjectGroups.get(i).onSizeChange(width, height);
			}
			if (mHasSurfaceCreated && mHadSize) {
				start();
			}
		}
	};

	public AnimSurfaceView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public AnimSurfaceView(Context context) {
		super(context);
		init();
	}

	/**
	 * 初始化
	 */
	protected void init() {
		// 开始绘制子线程
		mDrawThread = new HandlerThread("AnimSurfaceView-DrawThread");
		mDrawThread.start();
		getHolder().setFormat(PixelFormat.TRANSPARENT);
		getHolder().addCallback(mSurfaceCallback);
		// 此处用的是mDrawThread.getLooper()，发送给该Handler的都在DrawThread子线程执行
		mAnimFrameController = new AnimFrameController(this, mDrawThread.getLooper());
		mAnimClock = new AnimClock();
	}

	@Override
	protected void onWindowVisibilityChanged(int visibility) {
		super.onWindowVisibilityChanged(visibility);
		if (visibility == View.VISIBLE) {
			if (mHasSurfaceCreated && mHadSize) {
				start();
			}
		} else {
			stop();
		}
	}

	@Override
	protected void onDetachedFromWindow() {
		super.onDetachedFromWindow();
		stop();
	}

	/**
	 * 添加一个AnimObjectGroup
	 */
	@Override
	public void addAnimObjectGroup(AnimObjectGroup group) {
		mAnimObjectGroups.add(group);
	}

	/**
	 * 移除一个AnimObjectGroup
	 */
	@Override
	public void removeAnimObjectGroup(AnimObjectGroup group) {
		mAnimObjectGroups.remove(group);
	}

	/**
	 * 开始
	 */
	@Override
	public void start() {
		mAnimFrameController.start();
		mAnimClock.start();
	}

	/**
	 * 停止
	 */
	@Override
	public void stop() {
		mAnimFrameController.stop();
		mDrawThread.quit();
	}

	@Override
	public int getAnimSceneWidth() {
		return mDrawRect.width();
	}

	@Override
	public int getAnimSceneHeight() {
		return mDrawRect.height();
	}

	/**
	 * 设置帧频
	 */
	@Override
	public void setFtp(int ftp) {
		mAnimFrameController.setFtp(ftp);
	}

	/**
	 * 自身绘制
	 */
	protected void  drawself(Canvas canvas, int sceneWidth, int sceneHeight) {
	}

	@Override
	public void onUpdateFrame() {
		if (!mHasSurfaceCreated || !mHadSize) {
			return;
		}
		final SurfaceHolder holder = getHolder();
		if (holder == null || holder.isCreating()
				|| holder.getSurface() == null
				|| !holder.getSurface().isValid()) {
			return;
		}
		Canvas lockCanvas = null;
		try {
			// 获取Canvas
			lockCanvas = holder.lockCanvas(mDrawRect);
			if (null != lockCanvas) {
				// 逻辑
				for (int i = 0; i < mAnimObjectGroups.size(); i++) {
					mAnimObjectGroups.get(i).logic(mAnimClock.getAnimTime(), mAnimClock.getDeltaTime());
				}
				drawself(lockCanvas, mDrawRect.width(), mDrawRect.height());
				// 开始绘制
				for (int i = 0; i < mAnimObjectGroups.size(); i++) {
					mAnimObjectGroups.get(i).draw(lockCanvas, mDrawRect.width(), mDrawRect.height());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (lockCanvas != null) {
				try {
					holder.unlockCanvasAndPost(lockCanvas);
				} catch (Exception e) {
					e.printStackTrace();
				}
				mAnimFrameController.updateFrame();
				mAnimClock.updateFrame();
			}
		}
	}
}
